package org.nvframe.camera;

import java.util.ArrayList;
import java.util.List;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Input;
import org.newdawn.slick.geom.Vector2f;
import org.nvframe.camera.plugin.CameraPlugin;

public class Camera {
	
	private static Camera _instance = new Camera();
	
	public static Camera getInstance() {
		return _instance;
	}
	
	private Vector2f position;
	private Vector2f localPosition;
	private List<CameraPlugin> plugins;
	
	/**
	 * create a Camera instance
	 * 
	 * @param followEntity the entity to follow
	 */
	private Camera() {
		position = new Vector2f(0, 0);
		localPosition = new Vector2f(0, 0);
		plugins = new ArrayList<CameraPlugin> ();
	}
	
	/**
	 * add a cameraplugin to the effects arraylist
	 * 
	 * @param plugin implements CameraPlugin
	 */
	public void addPlugin(CameraPlugin plugin) {
		plugin.setCamera(this);
		plugins.add(plugin);
	}

	public Vector2f getPosition() {
		return position.copy();
	}	
	
	public void setPosition(Vector2f position) {
		this.position = position;
	}

	public Vector2f getLocalPosition() {
		return localPosition.copy();
	}

	public void setLocalPosition(Vector2f localPosition) {
		this.localPosition = localPosition;
	}

	public float getX() {
		return position.getX();
	}

	public float getY() {
		return position.getY();
	}

	public void setX(float x) {
		position.set(x, position.getY());
	}

	public void setY(float y) {
		position.set(position.getX(), y);
	}

	public void setPosition(float x, float y) {
		setX(x);
		setY(y);
	}
	
	/**
	 * Translate coords to the viewport context
	 * 
	 * @param gc
	 */
	public void translateGraphics(GameContainer gc) {
		gc.getGraphics().translate(-position.x - localPosition.x, 
				-position.y - localPosition.y);
	}
	
	/**
	 * undo viewport translation
	 * 
	 * @param gc
	 */
	public void untranslateGraphics(GameContainer gc) {
		gc.getGraphics().translate(position.x + localPosition.x, 
				position.y + localPosition.y);
	}

	/**
	 * get the x coordinate of the mouse translated to the camera position
	 * 
	 * @param input
	 * @return The x coord of mouse
	 */
	public int getMouseX(Input input) {
		return input.getMouseX() + (int) (position.x + localPosition.x);
	}
	
	/**
	 * get the y coordinate of the mouse translated to the camera position
	 * 
	 * @param input
	 * @return The Y coord of mouse
	 */
	public int getMouseY(Input input) {
		return input.getMouseY() + (int) (position.y + localPosition.y);
	}
}
